home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 135 (1990-05-15)(Ossowski, Stefan)(DE)(PD)[v Disaster Master 2].zip / Taifun 135 (1990-05-15)(Ossowski, Stefan)(DE)(PD)[v Disaster Master 2].adf / TurboMandel / source / TurboMandel.c < prev   
C/C++ Source or Header  |  1990-02-23  |  39KB  |  1,196 lines

  1. /*******************************
  2. *   TURBOMANDEL 1.0            *
  3. *           by Philip Marivoet *
  4. *              Nico Francois   *
  5. *******************************/
  6.  
  7. #include <exec/types.h>
  8. #include <exec/memory.h>
  9. #include <exec/execbase.h>
  10. #include <intuition/intuition.h>
  11. #include <intuition/intuitionbase.h>
  12. #include <hardware/custom.h>
  13. #include <graphics/copper.h>
  14. #include <graphics/gfxmacros.h>
  15. #include <stdio.h>
  16. #include <math.h>
  17. #include <libraries/arpbase.h>
  18. #include <proto/arp.h>
  19. #include <proto/intuition.h>
  20. #include <proto/dos.h>
  21. #include <proto/exec.h>
  22. #include <proto/graphics.h>
  23.  
  24. extern struct Custom __far custom;
  25.  
  26. #define ISCHECKED(x) (x.Flags & CHECKED)
  27. #define CHECK(x)     (x.Flags |=CHECKED)
  28. #define UNCHECK(x)   (x.Flags &=~CHECKED)
  29. #define TITLECHECK   ShowTitle(ManScr,(ISCHECKED(TitleItem) ? TRUE : FALSE))
  30.  
  31. /* assembler function call structure */
  32. extern LONG __asm Int32Mand_asm(register __a0 LONG,register __a1 LONG,register __d0 LONG);
  33. extern LONG __asm FloatMand_asm(register __a0 float,register __a1 float,register __d0 LONG);
  34. extern void __asm DoCycle_asm();
  35. extern void __asm PaletteLeft();
  36. extern void __asm PaletteRight();
  37. extern void __asm F2I(register __a0 ULONG *,register __d0 float);
  38. extern float __asm I2F(register __a0 ULONG *);
  39.  
  40. /**********
  41. * Palette *
  42. **********/
  43.  
  44. #define OK        10
  45. #define CANCEL    11
  46. #define RED       12
  47. #define GREEN     13
  48. #define BLUE      14
  49. #define INTPLUS   15
  50. #define INTMIN    16
  51. #define SLOPEPLUS 17
  52. #define SLOPEMIN  18
  53. #define TOPRIGHT  19
  54. #define TOPLEFT   20
  55.  
  56. SHORT BorderVectors1[] = { 0,0,26,0,26,11,0,11,0,0 };
  57. SHORT BorderVectors2[] = { 0,0,52,0,52,12,0,12,0,0 };
  58. struct Border Border26x11 = { -2,-1,3,0,JAM1,5,BorderVectors1,NULL };
  59. struct Border Border52x12 = { -2,-1,3,0,JAM1,5,BorderVectors2,NULL };
  60.  
  61. #define MakeGText(n,x,y,t) struct IntuiText n =\
  62.    { 1,0,JAM1,x,y,NULL,(UBYTE *)t,NULL }
  63. MakeGText (DecrText,8,1,"-");
  64. MakeGText (IncrText,8,1,"+");
  65. MakeGText (RightText,8,1,">");
  66. MakeGText (LeftText,8,1,"<");
  67. MakeGText (GreenText,8,1,"G");
  68. MakeGText (RedText,8,1,"R");
  69. MakeGText (BlueText,8,1,"B");
  70. MakeGText (CancelText,1,2,"CANCEL");
  71. MakeGText (OkText,17,2,"OK");
  72.  
  73. #define MakeRText(n,x,y,t) struct IntuiText n =\
  74.    { 2,0,JAM1,x,y,NULL,(UBYTE *)t,NULL}
  75. MakeRText (BodyText,5,5,"");
  76. MakeRText (YesText,5,3,"");
  77. MakeRText (NoText,5,3,"");
  78.  
  79. struct IntuiText PText = { 1,0,JAM1,35,58,NULL,(UBYTE *)"P",NULL };
  80. struct IntuiText SText = { 1,0,JAM1,75,63,NULL,(UBYTE *)"S",&PText };
  81. struct IntuiText IText = { 1,0,JAM1,151,63,NULL,(UBYTE *)"I",&SText };
  82.  
  83. #define MakeGBox(n,p,x,y,t,id) struct Gadget n = {p,x,y,23,10,NULL\
  84.    ,RELVERIFY,BOOLGADGET,(APTR)&Border26x11,NULL,&t,NULL,NULL,id,NULL}
  85. MakeGBox (DecrIntG,NULL,123,69,DecrText,INTMIN);
  86. MakeGBox (IncrIntG,&DecrIntG,123,54,IncrText,INTPLUS);
  87. MakeGBox (DecrSlopeG,&IncrIntG,88,69,DecrText,SLOPEMIN);
  88. MakeGBox (IncrSlopeG,&DecrSlopeG,88,54,IncrText,SLOPEPLUS);
  89. MakeGBox (RightTopG,&IncrSlopeG,43,69,RightText,TOPRIGHT);
  90. MakeGBox (LeftTopG,&RightTopG,11,69,LeftText,TOPLEFT);
  91. MakeGBox (GreenG,&LeftTopG,219,54,GreenText,GREEN);
  92. MakeGBox (BlueG,&GreenG,261,54,BlueText,BLUE);
  93. MakeGBox (RedG,&BlueG,178,54,RedText,RED);
  94.  
  95. struct Gadget CancelGb = { &RedG,235,69,49,11,NULL,RELVERIFY,BOOLGADGET,
  96.    (APTR)&Border52x12,NULL,&CancelText,NULL,NULL,CANCEL,NULL };
  97. struct Gadget OkGb = { &CancelGb,178,69,49,11,NULL,RELVERIFY,BOOLGADGET,
  98.    (APTR)&Border52x12,NULL,&OkText,NULL,NULL,OK,NULL };
  99. struct NewWindow NewPalWin = { 14,88,292,85,0,1,RAWKEY+GADGETDOWN+GADGETUP,
  100.    WINDOWDRAG+ACTIVATE+RMBTRAP+NOCAREREFRESH,&OkGb,NULL,(UBYTE *)"Palette",
  101.    NULL,NULL,5,5,640,200,CUSTOMSCREEN };
  102.  
  103. /*********
  104. * Coords *
  105. *********/
  106.  
  107. SHORT Vectors1[] = { 0,0,187,0,187,9,0,9,0,0 };
  108. struct Border Border187x9 = { -1,-1,1,0,JAM1,5,Vectors1,NULL};
  109.  
  110. /* GADGETS */
  111. struct Gadget CancelG = { NULL,125,86,49,11,NULL,RELVERIFY,BOOLGADGET,
  112.    (APTR)&Border52x12,NULL,&CancelText,NULL,NULL,CANCEL,NULL };
  113. struct Gadget OkG = { &CancelG,23,86,49,11,NULL,RELVERIFY,BOOLGADGET,
  114.    (APTR)&Border52x12,NULL,&OkText,NULL,NULL,OK,NULL };
  115.  
  116. UBYTE bottomrighty[22], bottomrightx[22], toplefty[22], topleftx[22];
  117. struct StringInfo BRyGInfo = { bottomrighty,NULL,0,22,0,0,0,0,0,0,0,0,NULL };
  118. struct StringInfo BRxGInfo = { bottomrightx,NULL,0,22,0,0,0,0,0,0,0,0,NULL };
  119. struct StringInfo TLyGInfo = { toplefty,NULL,0,22,0,0,0,0,0,0,0,0,NULL };
  120. struct StringInfo TLxGInfo = { topleftx,NULL,0,22,0,0,0,0,0,0,0,0,NULL };
  121.  
  122. #define MakeCoordBox(n,p,x,y,info) struct Gadget n = {p,x,y,184,8,NULL,\
  123.    RELVERIFY+STRINGCENTER,STRGADGET,(APTR)&Border187x9,NULL,NULL,NULL,\
  124.    (APTR)&info,NULL,NULL }
  125. MakeCoordBox(BRyG,&OkG, 8,72,BRyGInfo);
  126. MakeCoordBox(BRxG,&BRyG,8,60,BRxGInfo);
  127. MakeCoordBox(TLyG,&BRxG,8,36,TLyGInfo);
  128. MakeCoordBox(TLxG,&TLyG,8,24,TLxGInfo);
  129.  
  130. struct IntuiText BRText =
  131.    { 1,0,JAM1,10,49,NULL,(UBYTE *)"Bottom right:",NULL };
  132. struct IntuiText TLText =
  133.    { 1,0,JAM1,10,13,NULL,(UBYTE *)"Top left:",&BRText };
  134.  
  135. struct NewWindow newcoowin = { 60,79,200,100,0,1,GADGETDOWN+GADGETUP,
  136.    WINDOWDRAG+ACTIVATE+RMBTRAP+NOCAREREFRESH,&TLxG,NULL,
  137.    (UBYTE *)"Enter Coordinates",NULL,NULL,5,5,640,200,CUSTOMSCREEN };
  138.  
  139. /***************
  140.  * filenamereq *
  141.  ***************/
  142.  
  143. #define STRING 180
  144.  
  145. SHORT BorderVectors3[] = { 0,0,165,0,165,12,0,12,0,1 };
  146. struct Border Border12x165 = { -3,-2,3,0,COMPLEMENT,5,BorderVectors3,NULL };
  147. struct StringInfo StringGInfo = { NULL,NULL,0,64,0,0,0,0,0,0,0,0,NULL };
  148. struct Gadget StringG = { NULL,20,20,160,9,NULL,RELVERIFY+STRINGCENTER,
  149.    STRGADGET,(APTR)&Border12x165,NULL,NULL,NULL,(APTR)&StringGInfo,STRING,NULL };
  150. struct NewWindow NewStringWin = { 0,0,200,40,0,1,GADGETUP,
  151.    WINDOWDRAG+ACTIVATE+NOCAREREFRESH,&StringG,NULL,
  152.    (UBYTE *)"Enter Filename",NULL,NULL,5,5,640,200,CUSTOMSCREEN };
  153.  
  154. /********
  155. * Menus *
  156. ********/
  157.  
  158. #define makeMenuText(x,s,off) struct IntuiText x = {\
  159.    3,1,COMPLEMENT,0,off,NULL,(UBYTE *)s,NULL }
  160. #define makeMenuTextCheck(x,s,o) struct IntuiText x = {\
  161.    3,1,COMPLEMENT,19,o,NULL,(UBYTE *)s,NULL }
  162. #define makeITEM(x,y,h,w,t) struct MenuItem x = { y,0,h,w,9,ITEMTEXT\
  163.    +ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,NULL,MENUNULL }
  164. #define makeITEMCheckME(x,y,h,w,t,me) struct MenuItem x = { y,0,h,w,9,CHECKIT\
  165.    +ITEMTEXT+ITEMENABLED+HIGHCOMP,me,(APTR)&t,NULL,NULL,NULL,MENUNULL }
  166. #define makeITEMc(x,y,h,w,t,c) struct MenuItem x = { y,0,h,w,9,ITEMTEXT+\
  167.    ITEMENABLED+HIGHCOMP+COMMSEQ,0,(APTR)&t,NULL,c,NULL,MENUNULL }
  168. #define makeITEMcCheckT(x,y,h,w,t,c) struct MenuItem x = {\
  169.    y,0,h,w,9,CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP+COMMSEQ,\
  170.    NULL,(APTR)&t,NULL,c,NULL,MENUNULL }
  171. #define makeSUBCheckME(x,y,h,w,l,t,me) struct MenuItem x = { y,l,h,w,9,\
  172.    CHECKIT+ITEMTEXT+ITEMENABLED+HIGHCOMP,me,(APTR)&t,NULL,NULL,NULL,MENUNULL }
  173. #define makeITEMCheckT(x,y,h,w,t) struct MenuItem x = { y,0,h,w,9,CHECKIT+\
  174.    ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,NULL,MENUNULL }
  175. #define makeITEMCheckTME(x,y,h,w,t,me) struct MenuItem x = { y,0,h,w,9,CHECKIT+\
  176.    ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,me,(APTR)&t,NULL,NULL,NULL,MENUNULL}
  177. #define makeITEMSub(x,y,h,w,t,s) struct MenuItem x = {\
  178.    y,0,h,w,9,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,&s,MENUNULL }
  179. #define makeSUBItem(x,y,h,w,l,t) struct MenuItem x = {\
  180.    y,l,h,w,9,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,NULL,MENUNULL }
  181. #define makeMENU(m,n,x,w,s,i) struct Menu m = { n,x,0,w,0,MENUENABLED,s,i }
  182.  
  183. /*************
  184. * Screenmenu *
  185. *************/
  186.  
  187. makeMenuTextCheck (HiresText,"Hires",1);
  188. makeMenuTextCheck (InterText,"Interlace",1);
  189. makeMenuTextCheck (EHBText,"EHB",1);
  190. makeMenuTextCheck (TurboText,"Turbo",1);
  191. makeMenuTextCheck (ThreeDText,"3-D",1);
  192. makeMenuText (NewScrText,"New Screen",1);
  193. makeMenuText (PaletteText,"Palette",1);
  194.  
  195. makeITEMc (PalItem,NULL,54,95,PaletteText,'P');
  196. makeITEM (NewScrItem,&PalItem,45,95,NewScrText);
  197. makeITEMCheckT (ThreeDItem,&NewScrItem,36,95,ThreeDText);
  198. makeITEMCheckTME (EHBItem,&ThreeDItem,27,95,EHBText,0x0002);
  199. makeITEMcCheckT (TurboItem,&EHBItem,18,95,TurboText,'T');
  200. makeITEMCheckTME (HiresItem,&TurboItem,9,95,HiresText,0x0008);
  201. makeITEMCheckT (InterItem,&HiresItem,0,95,InterText);
  202.  
  203. makeMENU (ScreenMenu,NULL,164,66,"Screen",&InterItem);
  204.  
  205. /***************
  206.  * fractalmenu *
  207.  ***************/
  208.  
  209. makeMenuTextCheck (SuperText,"Super",1);
  210. makeMenuTextCheck (BestText,"Best",1);
  211. makeMenuTextCheck (GoodText,"Good",1);
  212. makeMenuTextCheck (NormalText,"Normal",1);
  213. makeMenuTextCheck (LowText,"Low",1);
  214.  
  215. makeSUBCheckME (SuperItem, NULL,24,67,73,SuperText,0x000F);
  216. makeSUBCheckME (BestItem,&SuperItem,16,67,73,BestText,0x0017);
  217. makeSUBCheckME (GoodItem,&BestItem,8,67,73,GoodText,0x001B);
  218. makeSUBCheckME (NormItem,&GoodItem,0,67,73,NormalText,0x001D);
  219. makeSUBCheckME (LowItem,&NormItem,-8,67,73,LowText,0x001E); 
  220.  
  221. makeMenuTextCheck (D32Text,"32",1);
  222. makeMenuTextCheck (D64Text,"64",1);
  223. makeMenuTextCheck (D128Text,"128",1);
  224. makeMenuTextCheck (D256Text,"256",1);
  225. makeMenuTextCheck (D512Text,"512",1);
  226. makeMenuTextCheck (D1024Text,"1024",1);
  227. makeMenuTextCheck (DCustText,"Custom",1);
  228.  
  229. makeSUBCheckME (DCustItem,NULL,40,68,73,DCustText,0x3F);
  230. makeSUBCheckME (D1024Item,&DCustItem,32,68,73,D1024Text,0x5F);
  231. makeSUBCheckME (D512Item,&D1024Item,24,68,73,D512Text,0x6F);
  232. makeSUBCheckME (D256Item,&D512Item,16,68,73,D256Text,0x77);
  233. makeSUBCheckME (D128Item,&D256Item, 8,68,73,D128Text,0x7B);
  234. makeSUBCheckME (D64Item,&D128Item, 0,68,73,D64Text,0x7D);
  235. makeSUBCheckME (D32Item,&D64Item,-8,68,73,D32Text,0x7E);
  236.  
  237. makeMenuTextCheck (IntText,"Integer",1);
  238. makeMenuTextCheck (FloatText,"Float",1);
  239.  
  240. makeSUBCheckME (FloatItem,NULL,0,75,73,FloatText,0x0001);
  241. makeSUBCheckME (IntItem,&FloatItem,-8,75,73,IntText,0x0002);
  242.  
  243. makeMenuText (AccText,"Accuracy",1);
  244. makeMenuText (DepthText,"Depth",1);
  245. makeMenuText (CalcText,"Calculation",1);
  246. makeMenuText (CoordText,"Coords",1);
  247. makeMenuText (ResetText,"Reset",1);
  248. makeMenuText (RestText,"Restart",1);
  249.  
  250. makeITEM (RestItem,NULL,45,88,RestText);
  251. makeITEM (ResetItem,&RestItem,36,88,ResetText);
  252. makeITEMc (CoordItem,&ResetItem,27,88,CoordText,'C');
  253. makeITEMSub (CalcItem,&CoordItem,18,88,CalcText,IntItem);
  254. makeITEMSub (DepthItem,&CalcItem,9,88,DepthText,D32Item);
  255. makeITEMSub (AccItem,&DepthItem,0,88,AccText,LowItem);
  256.  
  257. makeMENU (MandelMenu,&ScreenMenu,82,75,"Mandel",&AccItem);
  258.  
  259. /***************
  260.  * ProjectMenu *
  261.  ***************/
  262.  
  263. makeMenuText (AboutText,"About",1);
  264. makeMenuText (LoadText,"Load",1);
  265. makeMenuText (SaveText,"Save",1);
  266. makeMenuTextCheck (TitleText,"Title",1);
  267. makeMenuText (QuitText,"Quit",1);
  268.  
  269. makeITEMc (QuitItem,NULL,36,80,QuitText,'Q');
  270. makeITEMCheckT (TitleItem,&QuitItem,27,80,TitleText);
  271. makeITEMc (AboutItem,&TitleItem,18,80,AboutText,'A');
  272. makeITEMc (SaveItem,&AboutItem,9,80,SaveText,'S');
  273. makeITEMc (LoadItem,&SaveItem,0,80,LoadText,'L'); 
  274.  
  275. makeMENU (ProjectMenu,&MandelMenu,0,75,"Project",&LoadItem);
  276.  
  277. #define PROJECT    0
  278. #define LOAD          0
  279. #define SAVE          1
  280. #define ABOUT         2
  281. #define TITLE         3
  282. #define QUIT          4
  283. #define MANDEL     1
  284. #define ACCURACY      0
  285. #define SUPER             4
  286. #define DEPTH         1
  287. #define CUSTOMD           6
  288. #define CALCULATION   2
  289. #define INTCALC           0
  290. #define FLOATCALC         1
  291. #define COORD         3
  292. #define RESET         4
  293. #define RESTART       5
  294. #define SCREEN     2
  295. #define TURBO         2
  296. #define NEWSCR        5
  297. #define PALETTE       6
  298.  
  299. struct TextAttr TOPAZ80 = { (STRPTR)"topaz.font",TOPAZ_EIGHTY,0,0 };
  300. struct NewScreen ScrStruct = { 0,0,320,256,5,0,1,NULL,CUSTOMSCREEN,&TOPAZ80,
  301.    (UBYTE *)"TurboMandel V1.0",NULL,NULL};
  302. struct NewWindow WinStruct = { 0,0,320,256,0,1,RAWKEY+MENUPICK+MOUSEBUTTONS
  303.    +MOUSEMOVE,BORDERLESS+NOCAREREFRESH+ACTIVATE+BACKDROP,NULL,NULL,NULL,
  304.    NULL,NULL,640,512,640,512,CUSTOMSCREEN};
  305. USHORT Palette[32] = { 0x3a,0xfff,0x2,0xf00 };
  306.  
  307.  
  308.  
  309. /* for IFF read/write */
  310.  
  311. struct BitMapHeader {
  312.    UWORD w, h, x, y;
  313.    UBYTE nPlanes, masking, compression, pad1;
  314.    UWORD transparentColor;
  315.    UBYTE xAspect, yAspect;
  316.    WORD pageWidth, pageHeight;
  317.    };
  318. struct ILBM_info {
  319.    struct BitMapHeader header;
  320.    struct BitMap bitmap;
  321.    UBYTE cmap[32*3];
  322.    };
  323. extern BOOL iff_read(), iff_write();
  324. struct ILBM_info myILBMinfo;
  325.  
  326.  
  327. #define CALC_FFP     0
  328. #define CALC_INT32   1
  329. #define MAND_3D      1
  330.  
  331. struct MandelChunk {
  332.    ULONG XCoo[2], YCoo[2], XSide[2], YSide[2];
  333.    UWORD Iteration;
  334.    UBYTE Calculation, Flags;
  335.    SHORT TopPos[3], DecrStep[3], ColInt[3];      /* for Palette */
  336.    } MandChunk;
  337.  
  338.  
  339. struct FileRequester *req = NULL;
  340.  
  341. extern struct Library *MathTransBase;
  342. extern struct Library *MathBase;
  343. extern struct ExecBase *SysBase;
  344. struct ArpBase *ArpBase;
  345. struct IntuitionBase *IntuitionBase;
  346. struct GfxBase *GfxBase;
  347.  
  348. struct Screen *ManScr = NULL;
  349. struct Window *ManWin = NULL,*PalWin,*CoordWin,*StringWin;
  350. struct ViewPort *Manvp;
  351. struct RastPort *Manrp,*Palrp,*Coordrp;
  352.  
  353. void (*Dot)(), Dot2D(), Dot3D(), (*Box)(), Box2D(), Box3D();
  354. LONG (*Mand)(), FloatMand(), Int32Mand();
  355. LONG (*CalcMandel)(), CalcMandel2D(), CalcMandel3D();
  356. void AdjustArpReq (ULONG, struct NewWindow *);
  357. UBYTE *GetName ();
  358. double cos();
  359. LONG MaxIter, Depth, TurboDepth, DotsH, DotsV, ColorMax;
  360. LONG XOffset, YOffset, NumCol, XRes, YRes, Factor;
  361. SHORT StopCalc, Stopped, Restart = TRUE, CalcAllPoints, DivDegree, DivNumber;
  362. SHORT i, BoxOn = FALSE, CycleOn = FALSE, CycleTemp, CycleLeft = TRUE;
  363. SHORT PaletteOn = FALSE, CycleSpeed = 4, CurrSpeed = 4, NoZoom = FALSE;
  364. UBYTE fname[64], ItBuffer[64];
  365. float xmin, xmax, ymin, ymax, dx, dy;
  366. LONG ScrH;
  367.  
  368. #define PI2    1.570796327
  369. #define R      0
  370. #define G      1
  371. #define B      2
  372. SHORT toppos[3] = { 7,14,21 }, decrstep[3] = { 17,17,17 };
  373. SHORT colint[3] = { 15,15,15 };
  374.  
  375. main()
  376. {
  377.     if (ArpBase = (struct ArpBase *)OpenLibrary ("arp.library",0L)) {
  378.         if (req = ArpAllocFreq()) {
  379.             req->fr_Function = AdjustArpReq;
  380.             req->fr_FuncFlags = FRF_NewWindFunc;
  381.             req->fr_Window = 0;
  382.             }
  383.         }
  384.  
  385.     if (!(MathTransBase=(struct Library *)OpenLibrary("mathtrans.library",0L))) {
  386.       puts ("No mathtrans.library !");
  387.       exit (20);
  388.       }
  389.     if (!(MathBase=(struct Library *)OpenLibrary("mathffp.library",0L))) {
  390.         CloseLibrary (MathTransBase);
  391.       puts ("No math.library !");
  392.       exit (20);
  393.       }
  394.    IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L);
  395.    GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L);
  396.  
  397.     /* PAL or NTSC ? */
  398.     ScrH = (SysBase->VBlankFrequency == 60) ? 200 : 256;
  399.  
  400.    PalSinus (R); PalSinus (G); PalSinus (B);
  401.    xmax = 1.25; xmin = -2.25; ymax = 1.5; ymin = -1.5;
  402.    MaxIter = 64 ; CHECK (D64Item);
  403.    DivNumber = 2 ; CHECK (NormItem);
  404.    Mand = Int32Mand; CHECK (IntItem);
  405.  
  406.    while (Restart) {
  407.       if (!OpenDisplay()) {
  408.          UNCHECK(HiresItem); UNCHECK(InterItem);
  409.          if (! OpenDisplay()) CloseStuff();
  410.          Message("Not enough memory for screen ",NULL,"Proceed");
  411.       }
  412.       StopCalc = Stopped = Restart = FALSE;
  413.       dx = (xmax-xmin) / DotsH; dy = (ymax-ymin) / DotsV;
  414.       NoZoom = ISCHECKED(ThreeDItem) != NULL;
  415.       SubDivide (0L,0L,(LONG)(DotsH-1),(LONG)(DotsV-1));
  416.       UNCHECK(TurboItem); SetDepth();
  417.       while (!Stopped && !Restart) {
  418.          WaitPort(ManWin->UserPort);
  419.          TestInput();
  420.       }
  421.    }
  422.    CloseStuff();
  423. }
  424.  
  425. /* General routines */
  426.  
  427. CloseStuff()
  428. {
  429.    DisableCycle();
  430.    if (ManWin) {
  431.       ClearMenuStrip (ManWin);
  432.       CloseWindow (ManWin);
  433.    }
  434.    if (ManScr) CloseScreen (ManScr);
  435.    if (MathTransBase) CloseLibrary ((struct Library *)MathTransBase);
  436.    if (MathBase) CloseLibrary ((struct Library *)MathBase);
  437.    CloseLibrary ((struct Library *)GfxBase);
  438.    CloseLibrary ((struct Library *)IntuitionBase);
  439.    if (ArpBase) CloseLibrary ((struct Library *)ArpBase);
  440. }
  441.  
  442. OpenDisplay()
  443. {
  444.    CycleTemp = CycleOn; DisableCycle();
  445.    if (ManWin != NULL) {
  446.       ClearMenuStrip(ManWin);
  447.       CloseWindow(ManWin);
  448.       ManWin = NULL;
  449.    }
  450.    if (ManScr != NULL) {
  451.       CloseScreen(ManScr);
  452.       ManScr = NULL;
  453.    }
  454.    ScrStruct.ViewModes = (ISCHECKED(InterItem) ? LACE  : NULL) 
  455.       + (ISCHECKED(HiresItem)  ? HIRES : NULL)
  456.       + (ISCHECKED(EHBItem) ? EXTRA_HALFBRITE : NULL);
  457.    YRes = WinStruct.Height = ScrStruct.Height = (ISCHECKED(InterItem) ? (ScrH * 2) : ScrH);
  458.    XRes = WinStruct.Width = ScrStruct.Width = (ISCHECKED(HiresItem) ? 640 : 320);
  459.    Factor = (YRes == (ScrH * 2) ? 1 : 2) * (XRes == 640 ? 2 : 1);
  460.    Depth = ScrStruct.Depth =
  461.       ((ISCHECKED(HiresItem) ? 4:5) + (ISCHECKED(EHBItem) ? 1 : 0));
  462.    TurboDepth = (ISCHECKED(HiresItem) ? 2 : 4);
  463.  
  464.    /* screen and window */
  465.    if (!(ManScr = OpenScreen(&ScrStruct))) return(FALSE);
  466.    WinStruct.Screen = ManScr;
  467.    if (!(ManWin = OpenWindow(&WinStruct))) return(FALSE);
  468.    Manrp = ManWin->RPort;   
  469.    Manvp = &(ManScr->ViewPort);
  470.    LoadRGB4(Manvp,Palette,(NumCol = ISCHECKED(HiresItem) ? 16L: 32L));
  471.    ColorMax = NumCol * (ISCHECKED(EHBItem) ? 2:1);
  472.    SetDepth();
  473.    UNCHECK(TitleItem); TITLECHECK;
  474.    SetMenuStrip (ManWin,&ProjectMenu);
  475.    if (CycleTemp) EnableCycle();
  476.    if (ISCHECKED(ThreeDItem)) {
  477.       XOffset = (DotsH = XRes/2)/2; YOffset = (DotsV = YRes/2)/2;
  478.       Dot = Dot3D; Box = Box3D;
  479.       CalcMandel = CalcMandel3D;
  480.    }
  481.    else {
  482.       DotsH = XRes; DotsV = YRes;
  483.       Dot = Dot2D; Box = Box2D;
  484.       CalcMandel = CalcMandel2D;
  485.    }
  486.    return(TRUE);
  487. }
  488.  
  489. SetDepth()            /* Turbo */
  490. {
  491.    struct UCopList *cl;
  492.    long dispconreg;
  493.  
  494.    CycleTemp = CycleOn; DisableCycle();
  495.    FreeVPortCopLists(Manvp);
  496.    dispconreg = (Manvp->Modes & ~EXTRA_HALFBRITE) & 0x8fff;
  497.    dispconreg |= (ISCHECKED(TurboItem)? TurboDepth : Depth) << 12;
  498.    cl = (struct UCopList *)AllocMem ((LONG)sizeof(struct UCopList)
  499.       ,MEMF_PUBLIC|MEMF_CLEAR);
  500.    CWAIT (cl, 0L, 1L); CMOVE (cl, custom.bplcon0, dispconreg); CEND (cl);
  501.    Manvp->UCopIns = cl;
  502.    MakeScreen(ManScr); RethinkDisplay();
  503.    if (CycleTemp) EnableCycle();
  504. }
  505.  
  506. CalcNewPar(x1,y1,x2,y2)
  507. LONG x1,y1,x2,y2;
  508. {
  509.    LONG res;
  510.  
  511.    if (x2<x1) { res=x1; x1=x2; x2=res; }
  512.    if (y2<y1) { res=y1; y1=y2; y2=res; }
  513.    xmax = xmin + x2*dx; xmin = xmin + x1*dx;
  514.    ymin = ymax - y2*dy; ymax = ymax - y1*dy;
  515. }
  516.  
  517. Message(Text,Yes,No)
  518. UBYTE *Text,*Yes,*No;
  519. {
  520.    ULONG width;
  521.  
  522.    width = 40L + TextLength (Manrp,Text,(LONG)strlen(Text));
  523.    BodyText.IText = Text; BodyText.LeftEdge = 10L;
  524.    YesText.IText = Yes; NoText.IText = No;
  525.    return (AutoRequest(ManWin,&BodyText,Yes ? &YesText:NULL,&NoText,
  526.       NULL,NULL,width,50L));
  527. }
  528.  
  529. CompBox(x,y,Distx,Disty)
  530. LONG x,y,Distx,Disty;
  531. {
  532.    SetDrMd (Manrp,COMPLEMENT);
  533.    BoxOn = !BoxOn;
  534.    Move(Manrp,x-Distx,y-Disty);
  535.    Draw(Manrp,x+Distx,y-Disty); Draw(Manrp,x+Distx,y+Disty);
  536.    Draw(Manrp,x-Distx,y+Disty); Draw(Manrp,x-Distx,y-Disty);
  537.    SetDrMd (Manrp,JAM1);
  538. }
  539.  
  540. /* Change coordinates */
  541.  
  542. SetCoords ()
  543. {
  544.    SHORT Exit = FALSE,RCode = FALSE;
  545.    UWORD id;
  546.    float res;
  547.    struct IntuiMessage *msg,im;
  548.    struct Gadget *ActG;
  549.  
  550.    newcoowin.LeftEdge = (XRes-200)/2; newcoowin.TopEdge =  (YRes-100)/2;
  551.    newcoowin.Screen = ManScr;
  552.    if (!(CoordWin = OpenWindow (&newcoowin))) {
  553.       Message ("Can't open window !",NULL,"Proceed");
  554.       return (FALSE);
  555.    }
  556.    Coordrp = CoordWin->RPort;
  557.    PrintIText(Coordrp,&TLText,0L,0L);
  558.    sprintf (topleftx, "%f", xmin); sprintf (toplefty, "%f", ymax);
  559.    sprintf (bottomrightx, "%f", xmax); sprintf (bottomrighty, "%f", ymin);
  560.    RefreshGList (&TLxG, CoordWin, NULL, 4L);
  561.    ActivateGadget (&TLxG, CoordWin, NULL);
  562.    ActG = &TLxG;
  563.  
  564.    while (!Exit) {
  565.       WaitPort (CoordWin->UserPort);
  566.       msg = (struct IntuiMessage *)GetMsg(CoordWin->UserPort);
  567.          im = *msg;
  568.          ReplyMsg (msg);
  569.          id = ((struct Gadget *)im.IAddress)->GadgetID;
  570.          switch (im.Class) {
  571.             case GADGETUP:
  572.                switch (id) {
  573.                   case OK:
  574.                      sscanf (topleftx, "%f", &xmin);
  575.                      sscanf (toplefty, "%f", &ymax);
  576.                      sscanf (bottomrightx, "%f", &xmax);
  577.                      sscanf (bottomrighty, "%f", &ymin);
  578.                      Exit = RCode = TRUE;
  579.                   break;
  580.                   case CANCEL:
  581.                      Exit = TRUE;
  582.                      RCode = FALSE;
  583.                      break;
  584.                   default:
  585.                      ActG = (ActG == &BRyG ? &TLxG : ActG->NextGadget);
  586.                      ActivateGadget (ActG, CoordWin, NULL);
  587.                      break;
  588.                }
  589.          }
  590.    }
  591.    if (xmax < xmin) { res=xmax; xmax=xmin; xmin=res; }
  592.    if (ymax < ymin) { res=ymax; ymax=ymin; ymin=res; }
  593.    CloseWindow (CoordWin);
  594.    return ((int)RCode);
  595. }
  596.  
  597. /* Palette */
  598.  
  599. SetPalette()
  600. {
  601.    struct IntuiMessage *msg, im;
  602.    UBYTE exit = FALSE,TurboOn;
  603.    int i, id, oldpos[3], oldstep[3], oldint[3];
  604.    ULONG colw, lcol;
  605.    static int color = R;
  606.  
  607.    CycleTemp = CycleOn; DisableCycle();
  608.    PaletteOn = TRUE;
  609.    TurboOn = ISCHECKED(TurboItem);
  610.    UNCHECK(TurboItem); SetDepth();
  611.    NewPalWin.LeftEdge = (XRes - 292) / 2;
  612.    NewPalWin.TopEdge = (YRes - 85) / 2;
  613.    NewPalWin.Screen = ManScr;
  614.    if (!(PalWin = OpenWindow(&NewPalWin))) {
  615.       Message ("Can't open window !",NULL,"Proceed");
  616.       return;
  617.    }
  618.    Palrp = PalWin->RPort;
  619.    PrintIText (Palrp,&IText,0L,0L);
  620.    colw = (NumCol == 16) ? 23 : 10; lcol = (NumCol == 16) ? 8 : 6;
  621.    for (i = 0; i < NumCol - 4; i++ ) {
  622.       SetAPen (Palrp,(LONG)i + 4L);
  623.       RectFill (Palrp, lcol + i * colw, 15L, lcol - 1 + (i + 1) * colw, 47L);
  624.    }
  625.    SelectRGB (color);
  626.    for (i = 0; i < 3; i++) {
  627.       oldint[i] = colint[i]; oldstep[i] = decrstep[i]; oldpos[i] = toppos[i];
  628.    }
  629.    while (!exit) {
  630.       WaitPort (PalWin->UserPort);
  631.       msg = (struct IntuiMessage *)(GetMsg (PalWin->UserPort));
  632.       im = *msg;
  633.       ReplyMsg (msg);
  634.       switch (im.Class) {
  635.          case RAWKEY: HandleRawkey (&im); break;
  636.          case GADGETUP:
  637.             id = ((struct Gadget *)im.IAddress)->GadgetID;
  638.             switch (id) {
  639.                case CANCEL:
  640.                   for (i = 0; i < 3; i++) {
  641.                      colint[i] = oldint[i];
  642.                      decrstep[i] = oldstep[i];
  643.                      toppos[i] = oldpos[i];
  644.                      }
  645.                   PalSinus (R); PalSinus (G); PalSinus (B);
  646.                case OK:
  647.                   exit = TRUE;
  648.                   break;
  649.                case RED:
  650.                   color = R; SelectRGB (color);
  651.                   break;
  652.                case GREEN:
  653.                   color = G; SelectRGB (color);
  654.                   break;
  655.                case BLUE:
  656.                   color = B; SelectRGB (color);
  657.                   break;
  658.                case TOPLEFT:
  659.                   toppos[color] = (--toppos[color] < 4) ? 31 : toppos[color];
  660.                   break;
  661.                case TOPRIGHT:
  662.                   toppos[color] = (++toppos[color] > 31) ? 4 : toppos[color];
  663.                   break;
  664.                case SLOPEMIN:
  665.                   if (--decrstep[color] < 15) {
  666.                      decrstep[color] = 15; DisplayBeep (ManScr);
  667.                      }
  668.                   break;
  669.                case SLOPEPLUS:
  670.                   if (++decrstep[color] > 40) {
  671.                      decrstep[color] = 40; DisplayBeep (ManScr);
  672.                      }
  673.                   break;
  674.                case INTPLUS:
  675.                   if (++colint[color] > 0xf) {
  676.                      colint[color] = 0xf; DisplayBeep (ManScr);
  677.                      }
  678.                   break;
  679.                case INTMIN:
  680.                   if (--colint[color] < 0) {
  681.                      colint[color] = 0; DisplayBeep (ManScr);
  682.                   }
  683.                   break;
  684.                }
  685.             PalSinus (color);
  686.             LoadRGB4 (&ManScr->ViewPort, &Palette[0], 32L);
  687.             break;
  688.          }
  689.       }
  690.    if (TurboOn) { CHECK(TurboItem); SetDepth(); }
  691.    PaletteOn = FALSE;
  692.    if (CycleTemp) EnableCycle();
  693.    CloseWindow (PalWin);
  694. }
  695.  
  696. UWORD colmask[3] = { 0x0ff, 0x0f0f, 0xff0 };
  697.  
  698. PalSinus (color)
  699. int color;
  700. {
  701.    double x, xstep;
  702.    int pos1, pos2, i;
  703.    UWORD col, mask;
  704.  
  705.    x = 0; xstep = PI2 / decrstep[color];
  706.    pos1 = pos2 = toppos[color];
  707.    for (i = 0; i < 16; i++) {
  708.       col = cos (x) * colint[color];
  709.       mask = colmask[color];
  710.       if (color == R) col <<= 8; else if (color == G) col <<= 4;
  711.       Palette[pos1] = (Palette[pos1] & mask) | col;
  712.       Palette[pos2] = (Palette[pos2] & mask) | col;
  713.       x += xstep;
  714.       pos1 = (++pos1 > 31) ? 4 : pos1; pos2 = (--pos2 < 4) ? 31 : pos2;
  715.       }
  716. }
  717.  
  718. SelectRGB (color)
  719. int color;
  720. {
  721.    RedG.Flags &= ~SELECTED; BlueG.Flags &= ~SELECTED; GreenG.Flags &= ~SELECTED;
  722.    switch (color) {
  723.       case R: RedG.Flags |= SELECTED;break;
  724.       case G: GreenG.Flags |= SELECTED;break;
  725.       case B: BlueG.Flags |= SELECTED;break;
  726.    }
  727.    SetAPen (Palrp, 0L);
  728.    RectFill (Palrp, 174L, 52L, 286L, 66L);
  729.    RefreshGList (&RedG, PalWin, NULL, 3L);
  730. }
  731.  
  732. /* intuition event handling */
  733.  
  734. #define TAB    0x42
  735. #define UP     0x4c
  736. #define DOWN   0x4d
  737. #define LEFT   0x4f
  738. #define RIGHT  0x4e
  739.  
  740. HandleRawkey (msg)
  741. struct IntuiMessage *msg;
  742. {
  743.    switch (msg->Code) {
  744.       case TAB:
  745.          if (!PaletteOn) {
  746.             if (msg->Qualifier & (IEQUALIFIER_LSHIFT+IEQUALIFIER_RSHIFT))
  747.                CycleLeft = !CycleLeft;
  748.             else if (CycleOn) DisableCycle();
  749.             else EnableCycle();
  750.             }
  751.          break;
  752.       case UP:
  753.          if (CycleOn) if (CycleSpeed > 1) CurrSpeed = --CycleSpeed;
  754.          else DisplayBeep (ManScr);
  755.          break;
  756.       case DOWN:
  757.          if (CycleOn) CurrSpeed = ++CycleSpeed;
  758.          break;
  759.       case LEFT:
  760.          if (!CycleOn) {
  761.                 PaletteLeft();                
  762.             LoadRGB4 (Manvp, Palette, 32L);
  763.          }
  764.          break;
  765.       case RIGHT:
  766.          if (!CycleOn) {
  767.                 PaletteRight();
  768.             LoadRGB4 (Manvp, Palette, 32L);
  769.          }
  770.          break;
  771.       }
  772. }
  773.  
  774. TestInput()
  775. {
  776.    struct IntuiMessage *msg,im;
  777.    short DoLoop= TRUE, Zooming = FALSE;
  778.    LONG XCoord,YCoord,Distx,Disty;
  779.  
  780.    while (DoLoop){
  781.       if (msg=(struct IntuiMessage *)(GetMsg(ManWin->UserPort))) {
  782.          im = *msg;
  783.          ReplyMsg(msg);
  784.          switch (im.Class) {
  785.             case RAWKEY: HandleRawkey (&im); break;
  786.             case MENUPICK: switch (MENUNUM(im.Code)) {
  787.                case PROJECT:
  788.                   switch (ITEMNUM(im.Code)) {
  789.                      case LOAD: GetIff(); break;
  790.                      case SAVE: SaveIff(); break;
  791.                      case TITLE: TITLECHECK; break;
  792.                      case ABOUT:
  793.                         Message ("Programmed by Ph.Marivoet, N.Francois", NULL, "Proceed");
  794.                         break;
  795.                      case QUIT:
  796.                         if (Message("Do you want to quit","Yes","No"))
  797.                            Stopped = StopCalc = TRUE;
  798.                         break;
  799.                   }
  800.                   break;
  801.                case MANDEL:
  802.                   switch (ITEMNUM(im.Code)) {
  803.                      case COORD:
  804.                         if (SetCoords()) Restart = StopCalc = TRUE;
  805.                         break;
  806.                      case RESET:
  807.                         if (Message("Reset Mandel","Yes","No")) {
  808.                            xmax = 1.25; xmin = -2.25;
  809.                            ymax = 1.5; ymin = -1.5;
  810.                            StopCalc = Restart = TRUE;
  811.                         }
  812.                         break;
  813.                      case RESTART:
  814.                         if (Message("Restart Calculation","Yes","No"))
  815.                            StopCalc = Restart = TRUE;
  816.                         break;
  817.                      case ACCURACY:
  818.                         CalcAllPoints=((DivDegree=SUBNUM(im.Code))==SUPER);
  819.                         DivNumber = 1<<DivDegree;
  820.                         break;
  821.                      case DEPTH:
  822.                         if (SUBNUM(im.Code)==CUSTOMD) {
  823.                            if (GetName("Iteration",ItBuffer,FALSE))
  824.                               sscanf(ItBuffer,"%ld",&MaxIter);
  825.                         }
  826.                         else MaxIter = 1 << (SUBNUM(im.Code)+5);
  827.                         break;
  828.                      case CALCULATION:
  829.                         if (ISCHECKED(FloatItem)) Mand = FloatMand;
  830.                         else Mand = Int32Mand;
  831.                         break;
  832.                   }
  833.                   break;
  834.                case SCREEN:
  835.                   switch(ITEMNUM(im.Code)) {
  836.                      case NEWSCR:
  837.                         if (Message("New Screen","Yes","No"))
  838.                            StopCalc=Restart=TRUE;
  839.                         break;
  840.                      case TURBO: SetDepth(); break;
  841.                      case PALETTE: SetPalette(); break;
  842.                   }
  843.                   break;
  844.                } 
  845.                break;
  846.             case MOUSEBUTTONS:
  847.                if (!NoZoom)
  848.                   switch (im.Code) {
  849.                      case SELECTDOWN:
  850.                         Zooming = TRUE;
  851.                         XCoord = im.MouseX;
  852.                         YCoord = im.MouseY;
  853.                         Distx = Disty = 0;
  854.                         ReportMouse (ManWin , TRUE);
  855.                         break;
  856.                      case SELECTUP:
  857.                         Zooming = FALSE;
  858.                         ReportMouse (ManWin , TRUE);
  859.                         if (Distx != 0 && Disty != 0)
  860.                            if (Message("Zoom area in ?","Yes","No")) {
  861.                               CalcNewPar(XCoord-Distx,YCoord-Disty,
  862.                                          XCoord+Distx,YCoord+Disty);   
  863.                               StopCalc = Restart = TRUE;
  864.                            }
  865.                         if (BoxOn) CompBox(XCoord,YCoord,Distx,Disty);
  866.                         break;
  867.                   }
  868.                break;   
  869.             case MOUSEMOVE:
  870.                if (Zooming) {
  871.                   if (BoxOn) CompBox(XCoord,YCoord,Distx,Disty);
  872.                   Distx = XCoord-im.MouseX;
  873.                   Disty = YCoord-im.MouseY;
  874.                   CompBox(XCoord,YCoord,Distx,Disty);
  875.                   }
  876.                break;
  877.          }
  878.       }
  879.    DoLoop = Zooming;
  880.    }
  881. }
  882.  
  883. /* Function for ARP filerequester (requester on our screen) */
  884.  
  885. void AdjustArpReq (ULONG Mask, struct NewWindow *win)
  886. {
  887.     win->Screen = ManScr;
  888.     win->Type = CUSTOMSCREEN;
  889.     win->LeftEdge = (XRes-win->Width)/2;
  890.     win->TopEdge = (YRes-win->Height)/2;
  891. }
  892.  
  893.  
  894.  
  895. UBYTE *GetName (title, str, FileReq)
  896. UBYTE *title, *str;
  897. BOOL FileReq;
  898. {
  899.     static UBYTE Path[108];
  900.     UBYTE File[256];
  901.  
  902.     if (req && FileReq) {
  903.         req->fr_Hail = title;
  904.         req->fr_Dir = Path;
  905.         strcpy (str,FileRequest (req));
  906.         if (*str) {
  907.             strcpy (File,Path);
  908.             TackOn (File,str);
  909.             strcpy (str,File);
  910.             return (str);
  911.             }
  912.         else return (NULL);
  913.     }
  914.  
  915.    StringGInfo.Buffer = str;
  916.    NewStringWin.LeftEdge = (XRes-200)/2; NewStringWin.TopEdge = (YRes-40)/2;
  917.    NewStringWin.Screen = ManScr;
  918.    NewStringWin.Title = title;
  919.    if (!(StringWin = OpenWindow (&NewStringWin))) {
  920.       Message ("Can't open window !",NULL,"Proceed");
  921.       return (NULL);
  922.    }
  923.    ActivateGadget (&StringG, StringWin, NULL);
  924.    WaitPort (StringWin->UserPort);
  925.    CloseWindow (StringWin);
  926.     if (*str) return (str);
  927.     else return (NULL);
  928. }
  929.  
  930. /* IFF load/save */
  931.  
  932. GetIff()
  933. {
  934.    LONG d, i;
  935.    struct IntuiMessage *msg;
  936.  
  937.    if (!GetName("Load file", fname, TRUE)) return;
  938.    MandChunk.XSide[0] = NULL;
  939.    if (read_iff (&myILBMinfo,fname,1)) {
  940.       if (!MandChunk.XSide[0])
  941.          if (!Message ("MANDEL chunk not found, load anyway ?","Yes","No"))
  942.             return;
  943.         if ((myILBMinfo.header.h > (ScrH * 2)) || (myILBMinfo.header.w > 640)) {
  944.             Message ("Picture too large, can't load",NULL,"Ok");
  945.             return;
  946.         }
  947.         if ((myILBMinfo.header.w > 320) && (myILBMinfo.header.nPlanes > 5)) {
  948.             Message ("Picture too large, can't load",NULL,"Ok");
  949.             return;
  950.         }        
  951.       NoZoom = StopCalc = TRUE;
  952.       UNCHECK(TurboItem);
  953.       if ((d = myILBMinfo.header.nPlanes) > 5) { d = 5; CHECK(EHBItem); }
  954.       for (i = 0; i < 1<<d; i++)
  955.          Palette[i] = ((myILBMinfo.cmap[3 * i] & 0xf0) << 4)
  956.                      + (myILBMinfo.cmap[3 * i + 1] & 0xf0)
  957.                      +((myILBMinfo.cmap[3 * i + 2] & 0xf0) >> 4);
  958.       if (myILBMinfo.header.h > ScrH) CHECK (InterItem);
  959.       else UNCHECK (InterItem);
  960.       if (myILBMinfo.header.w > 320) CHECK (HiresItem);
  961.       else UNCHECK (HiresItem);
  962.       if (!OpenDisplay()) {
  963.          UNCHECK (HiresItem); UNCHECK (InterItem);
  964.          if (!OpenDisplay()) Stopped = TRUE;
  965.          else Message ("No memory for screen !",NULL,"Proceed");
  966.          }
  967.       else {
  968.          ModifyIDCMP (ManWin, MENUVERIFY);
  969.          if (MandChunk.XSide[0]) {
  970.             xmax = (xmin = I2F(MandChunk.XCoo)) + I2F(MandChunk.XSide);
  971.             ymax = (ymin = I2F(MandChunk.YCoo)) + I2F(MandChunk.YSide);
  972.             dx = (xmax-xmin) / DotsH;
  973.             dy = (ymax-ymin) / DotsV;
  974.             UNCHECK (D32Item); UNCHECK (D64Item); UNCHECK (D128Item);
  975.             UNCHECK (D256Item); UNCHECK (D512Item); UNCHECK (D1024Item);
  976.             UNCHECK (DCustItem);
  977.             switch (MaxIter = MandChunk.Iteration) {
  978.                case 32:   CHECK (D32Item); break;
  979.                case 64:   CHECK (D64Item); break;
  980.                case 128:  CHECK (D128Item); break;
  981.                case 256:  CHECK (D256Item); break;
  982.                case 512:  CHECK (D512Item); break;
  983.                case 1024: CHECK (D1024Item); break;
  984.                default:
  985.                   CHECK (DCustItem);
  986.                   sprintf (ItBuffer, "%ld", MaxIter);
  987.                   break;
  988.             }
  989.             UNCHECK (FloatItem); UNCHECK (IntItem);
  990.             if (MandChunk.Calculation == CALC_INT32) {
  991.                CHECK (IntItem); Mand = Int32Mand;
  992.             }
  993.             else {
  994.                CHECK (FloatItem); Mand = FloatMand;
  995.             }
  996.             if (MandChunk.Flags & MAND_3D)
  997.                CHECK (ThreeDItem);
  998.             else {
  999.                UNCHECK (ThreeDItem); NoZoom = FALSE;
  1000.                }
  1001.             for (i = 0; i < 3; i++) {
  1002.                toppos[i] = MandChunk.TopPos[i];
  1003.                decrstep[i] = MandChunk.DecrStep[i];
  1004.                colint[i] = MandChunk.ColInt[i];
  1005.             }
  1006.          }
  1007.          myILBMinfo.bitmap = ManScr->BitMap;
  1008.          myILBMinfo.bitmap.BytesPerRow = ((myILBMinfo.header.w+15)>>4)<<1;
  1009.          myILBMinfo.bitmap.Rows = myILBMinfo.header.h;
  1010.          myILBMinfo.bitmap.Depth = myILBMinfo.header.nPlanes;
  1011.          if (!read_iff (&myILBMinfo,fname, 0))
  1012.             Message ("Error loading file !",NULL,"Proceed");
  1013.       }
  1014.    }
  1015.    else Message ("Can't load IFF file !",NULL,"Proceed");
  1016.    while (msg = (struct IntuiMessage *)GetMsg (ManWin->UserPort))
  1017.       ReplyMsg (msg);
  1018.    ModifyIDCMP (ManWin, RAWKEY+MOUSEMOVE+MENUPICK+MOUSEBUTTONS);
  1019. }
  1020.  
  1021. SaveIff()
  1022. {
  1023.    struct IntuiMessage *msg;
  1024.  
  1025.    if (!GetName("Save file", fname, TRUE)) return;
  1026.    ModifyIDCMP (ManWin, MENUVERIFY);
  1027.    UNCHECK (TitleItem); TITLECHECK;
  1028.    F2I(MandChunk.XCoo, xmin); F2I(MandChunk.XSide, xmax - xmin);
  1029.    F2I(MandChunk.YCoo, ymin); F2I(MandChunk.YSide, ymax - ymin);
  1030.    MandChunk.Iteration = MaxIter;
  1031.    if (ISCHECKED(IntItem)) MandChunk.Calculation = CALC_INT32;
  1032.    else MandChunk.Calculation = CALC_FFP;
  1033.    MandChunk.Flags = 0;
  1034.    if (CalcMandel == CalcMandel3D) MandChunk.Flags |= MAND_3D;
  1035.    for (i = 0; i < 3; i++) {
  1036.       MandChunk.TopPos[i] = toppos[i];
  1037.       MandChunk.DecrStep[i] = decrstep[i];
  1038.       MandChunk.ColInt[i] = colint[i];
  1039.    }
  1040.    if (!write_iff (fname,&Palette[0], ManScr, 1))
  1041.       Message ("Couldn't save IFF file !",NULL,"Proceed");
  1042.    while (msg = (struct IntuiMessage *)GetMsg (ManWin->UserPort))
  1043.       ReplyMsg (msg);
  1044.    ModifyIDCMP (ManWin, RAWKEY+MOUSEMOVE+MENUPICK+MOUSEBUTTONS);
  1045.    DisplayBeep (ManScr);
  1046. }
  1047.  
  1048. /* 2D-3D subroutines */
  1049.  
  1050. LONG CalcMandel2D(ix,iy)
  1051. LONG ix,iy;
  1052. {
  1053.    LONG color;
  1054.    float x,y;
  1055.  
  1056.    if (!(color = ReadPixel(Manrp,ix,iy))) {
  1057.       x = xmin+ix*dx;
  1058.       y = ymax-iy*dy;
  1059.       color = Mand(x,y,MaxIter);
  1060.       SetAPen(Manrp,color);
  1061.       WritePixel(Manrp,ix,iy);
  1062.    }
  1063.    return(color);
  1064. }
  1065.  
  1066. LONG CalcMandel3D(ix,iy)
  1067. LONG ix,iy;
  1068. {
  1069.    return (Mand ((float)xmin+ix*dx, (float)ymax-iy*dy, MaxIter));
  1070. }
  1071.  
  1072. void Dot2D(x,y,col)
  1073. LONG x,y,col;
  1074. {
  1075.    SetAPen(Manrp,col); WritePixel(Manrp,x,y);
  1076. }
  1077.  
  1078. void Dot3D(x,y,col)
  1079. LONG x,y,col;
  1080. {
  1081.    SetAPen (Manrp, col == 2L ? 2L : (col == 4L ? 31L : col-1L));
  1082.    Move (Manrp, x+XOffset+(YOffset-y)*Factor/2, y+YOffset-col);
  1083.    Draw (Manrp, x+XOffset+(YOffset-y)*Factor/2, y+YOffset);
  1084.    SetAPen (Manrp,col);
  1085.    WritePixel (Manrp, x+XOffset+(YOffset-y)*Factor/2, y+YOffset-col);
  1086. }
  1087.  
  1088. void Box2D(x1,y1,x2,y2,col)
  1089. LONG x1,y1,x2,y2,col;
  1090. {
  1091.    SetAPen(Manrp,col); RectFill(Manrp,x1,y1,x2,y2);
  1092. }
  1093.  
  1094. void Box3D(x1,y1,x2,y2,col)
  1095. LONG x1,y1,x2,y2,col;
  1096. {
  1097.    LONG i, bcol;
  1098.  
  1099.    bcol = (col == 2L ? 2L : (col == 4L ? 31L : col-1L));
  1100.    SetAPen (Manrp, bcol);
  1101.    RectFill (Manrp, x1+XOffset+(YOffset-y2)*Factor/2, y2+YOffset-col,
  1102.                     x2+XOffset+(YOffset-y2)*Factor/2, y2+YOffset);
  1103.    for (i=y1; i<=y2; i++) {
  1104.       SetAPen (Manrp, bcol);
  1105.       Move (Manrp, x2+XOffset+(YOffset-i)*Factor/2, i+YOffset);
  1106.       Draw (Manrp, x2+XOffset+(YOffset-i)*Factor/2, i+YOffset-col);
  1107.       SetAPen(Manrp,col);
  1108.       Draw (Manrp, x1+XOffset+(YOffset-i)*Factor/2, i+YOffset-col);
  1109.    }
  1110. }
  1111.  
  1112. /* Recursive calculation of mandelbrot */
  1113.  
  1114. SubDivide(x1,y1,x2,y2)
  1115. LONG x1,x2,y1,y2;
  1116. {
  1117.    static LONG i,TestColor;
  1118.    LONG mx1,my1,mx2,my2,SameColor = TRUE,Step;
  1119.  
  1120.    if (StopCalc) return;
  1121.    if ((x1==x2) && (y1==y2)) {
  1122.       Dot(x1,y1,CalcMandel(x1,y1)); return;
  1123.    }
  1124.    mx1 = mx2 = (x1+x2)/2;
  1125.    my1 = my2 = (y1+y2)/2;
  1126.    TestColor = CalcMandel (mx1,my1);
  1127.  
  1128.    if (CalcAllPoints || !(Step=(x2-x1)/DivNumber)) Step = 1;
  1129.    for (i = 0; (i <= x2-x1) && !StopCalc; i += Step) {
  1130.       SameColor &= TestColor == CalcMandel (x1+i,y1);
  1131.       SameColor &= TestColor == CalcMandel (x2-i,y2);
  1132.       TestInput();
  1133.    }
  1134.  
  1135.    if (CalcAllPoints || !(Step=(y2-y1)/DivNumber)) Step = 1;
  1136.    for (i = 0 ;(i <= y2-y1) && !StopCalc; i += Step) {
  1137.       SameColor &= TestColor == CalcMandel (x1,y2-i);
  1138.       SameColor &= TestColor == CalcMandel (x2,y1+i);
  1139.       TestInput();
  1140.    }
  1141.    if (SameColor && !StopCalc) Box(x1,y1,x2,y2,TestColor);
  1142.    else {
  1143.       if ((x2-x1) == 1) mx2 = mx1 +1; if ((y2-y1) == 1) my2 = my1 +1;
  1144.       SubDivide (x1 ,y1 ,mx1,my1); SubDivide (x1 ,my2,mx1,y2 );
  1145.       SubDivide (mx2,y1 ,x2 ,my1); SubDivide (mx2,my2,x2 ,y2 );
  1146.    }
  1147. }
  1148.  
  1149.  
  1150. float fixedfactor = (float)(1L << 27);
  1151.  
  1152. LONG Int32Mand (px, py, max_iter)
  1153. float px, py;
  1154. LONG max_iter;
  1155. {
  1156.    register LONG color = 2;
  1157.     LONG itcountint;
  1158.  
  1159.     itcountint = Int32Mand_asm((long)(px * fixedfactor),(long)(py * fixedfactor),max_iter);
  1160.    if (itcountint) color = (max_iter - itcountint) % (ColorMax-4) + 4;
  1161.    return (color);
  1162. }
  1163.  
  1164.  
  1165. LONG FloatMand (px,py,max_iter)
  1166. float px,py;
  1167. LONG max_iter;
  1168. {
  1169.    LONG color = 2,itcount;
  1170.  
  1171.     itcount = FloatMand_asm(px,py,max_iter);
  1172.    if (itcount) color = (max_iter - itcount) % (ColorMax-4) + 4;
  1173.    return(color);
  1174. }
  1175.  
  1176. /* Cycle subtask */
  1177. void __saveds DoCycle()
  1178. {
  1179.     DoCycle_asm();
  1180. }
  1181.  
  1182. EnableCycle()
  1183. {
  1184.    struct Task *CycleTask;
  1185.  
  1186.    if (!CycleOn)
  1187.       CycleTask = (struct Task *)CreateTask ("TM VBlank", 2L, DoCycle, 1000L);
  1188.    CycleOn = TRUE;
  1189. }
  1190.  
  1191. DisableCycle()
  1192. {
  1193.    CycleOn = FALSE; WaitTOF(); WaitTOF();
  1194. }
  1195.  
  1196.